package com.study.ssm.mybatis.service.impl;

import com.study.ssm.mybatis.dao.UserMapper;
import com.study.ssm.mybatis.entity.User;
import com.study.ssm.mybatis.service.UserService;
import lombok.Getter;
import lombok.Setter;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author zhoujunlin
 * @date 2023年07月25日 10:26
 * @desc
 */
public class UserServiceImpl implements UserService {

    @Getter
    @Setter
    private UserMapper userMapper;

    /**
     * 隔离属性：Isolation
     * DEFAULT 默认值 使用数据库的默认隔离级别  mysql是可重复读
     * READ_UNCOMMITTED  读未提交 会有脏读问题
     * READ_COMMITTED    读已提交  解决脏读问题  会有不可重复读问题
     * REPEATABLE_READ   可重复度  解决不可重复读问题  存在幻读问题  mysql  mvcc解决了此问题
     * SERIALIZABLE      串行化    解决幻读问题
     * <p>
     * 传播属性：propagation  解决事务嵌套问题
     * REQUIRED 默认值  外部不存在事务：开启新事务  外部存在事务：融合    场景：增删改
     * REQUIRES_NEW    外部不存在事务：开启事务  外部存在事务：挂起外部事务，开启新事务    场景：记录日志 不重要的操作
     * SUPPORTS       外部不存在事务：不开启事务  外部存在事务：融合    场景：查询
     * MANDATORY      外部不存在事务：抛异常     外部存在事务：融合    场景：不常用
     * NOT_SUPPORTED  外部不存在事务：不开启事务  外部存在事务：挂起外部事务    场景：不常用
     * NEVER         外部不存在事务：不开启事务  外部存在事务：抛出异常    场景：不常用
     * <p>
     * 只读属性：readOnly  查询操作  readOnly提升效率
     * <p>
     * 超时属性：timeout  事务锁等待超时时间  默认-1  使用数据库默认的超时时间
     * <p>
     * 异常处理属性：
     * rollbackFor   针对xxx异常回滚
     * noRollbackFor  针对xxx异常不回滚 即提交
     *
     * @param user
     * @return
     */
    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, readOnly = false,
            timeout = -1, rollbackFor = Exception.class)
    public int save(User user) {
        userMapper.saveUser(user);
        // 默认回滚策略 RuntimeException
        //throw new RuntimeException("测试回滚");
        return 1;
    }

}
